/**********************************************************
 * AccountsManagerAction.java
 * Created by ankur
 * Last modified Date: Aug 5, 2008 11:37:54 AM by ankur
 * Version : 0.1
 * Copyright (c) 2008 - 2008 cyberThink Infotech Pvt. Ltd., All rights reserved.
 **********************************************************/
package com.printeverywhere.action;


import static com.printeverywhere.util.AttributeConstants.CITY;
import static com.printeverywhere.util.AttributeConstants.COMPANY;
import static com.printeverywhere.util.AttributeConstants.COUNTRY;
import static com.printeverywhere.util.AttributeConstants.EMAIL;
import static com.printeverywhere.util.AttributeConstants.FIRSTNAME;
import static com.printeverywhere.util.AttributeConstants.LASTNAME;
import static com.printeverywhere.util.AttributeConstants.OTHER;
import static com.printeverywhere.util.AttributeConstants.PHONE;
import static com.printeverywhere.util.AttributeConstants.SEARCH;
import static com.printeverywhere.util.AttributeConstants.SELECT_A_COUNTRY;
import static com.printeverywhere.util.AttributeConstants.STATE;
import static com.printeverywhere.util.AttributeConstants.STREET;
import static com.printeverywhere.util.AttributeConstants.SUBMIT;
import static com.printeverywhere.util.AttributeConstants.TOP;
import static com.printeverywhere.util.AttributeConstants.USER_ID;
import static com.printeverywhere.util.AttributeConstants.WEBSITEADDRESS;
import static com.printeverywhere.util.AttributeConstants.ZIP;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.util.ServletContextAware;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.util.ValueStack;
import com.printeverywhere.delegator.CommonFunctionDelegator;
import com.printeverywhere.delegator.LocationCategoriesServiceDelegator;
import com.printeverywhere.delegator.UserServiceDelegator;
import com.printeverywhere.dto.AccountManagerOption;
import com.printeverywhere.dto.LocationCategories;
import com.printeverywhere.dto.User;
import com.printeverywhere.dto.UserAccountsCount;
import com.printeverywhere.util.AdminConstants;
import com.printeverywhere.util.DisplayConstants;
import com.printeverywhere.util.SearchCriteria;
import com.printeverywhere.util.SearchListCriteria;
/**
 * The Class AccountsManagerAction.
 */
public class AccountsManagerAction extends AdminEngineManagement implements ServletContextAware {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(AccountsManagerAction.class);
	private static final String STATUS_UPDATE = "User status updated successfully";
	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 1L;
	private ServletContext application;
	private boolean page=false;
	private boolean paging=true;
	private Integer pageSize;

	/**
	 * @return the paging
	 */
	public boolean isPaging() {
		return paging;
	}

	/**
	 * @param paging the paging to set
	 */
	public void setPaging(boolean paging) {
		this.paging = paging;
	}

	/**
	 * @return the page
	 */
	public boolean isPage() {
		return page;
	}

	/**
	 * @param page the page to set
	 */
	public void setPage(boolean page) {
		this.page = page;
	}

	/**
	 * Populates  accountSearchList as per the criteria selected by Admin user
	 * userAccountsCount
	 * @see com.opensymphony.xwork2.ActionSupport#execute()
	 */
	public String execute() throws Exception{
		if(this.pageSize == null)
			this.pageSize = new Integer(10);
		clearMessages();
		country = new ArrayList<LocationCategories>();
		SearchListCriteria searchListCriteria = new SearchListCriteria();
		searchListCriteria.setAsc(true);
		searchListCriteria.setOrderBy(AdminConstants.CATEGORYNAME);
		searchListCriteria.setAttribute(AdminConstants.LEVEL, new Object[] {AdminConstants.ONE_NUMBER, SearchListCriteria.EQ });
		region = LocationCategoriesServiceDelegator.getList(searchListCriteria);
		regionList = new ArrayList<LocationCategories>(region);
		populateAccountSearchList();
		try{
			if(operation==null){
				page=true;
				if(group==null)
				ActionContext.getContext().getSession().remove("searchCriteria");
			}else{
				page=false;
			}

		if(userMap != null)
		if(operation != null && SUBMIT.equalsIgnoreCase(operation)){
			int i=0;
			for (Integer userKey : userMap.keySet()) {
				if(userKey!=null){
					User user = userMap.get(userKey);
					User userOld = userMapFlag.get(userKey);
					if(user.getActive() != userOld.getActive()){
						UserServiceDelegator.updateUserActive(user);
						i=1;
					}
				}
				if(i>0){
					Collection c= getActionMessages();
					if(!c.contains(STATUS_UPDATE))
					addActionMessage(STATUS_UPDATE);
				}
			}

			if(selectedUserDeleted!=null && selectedUserDeleted.length>0){
				for (String id : selectedUserDeleted) {
					List<User> users =null;
					try{
						SearchCriteria searchCriteria=new SearchCriteria();
						searchCriteria.setAttribute("id", Integer.parseInt(id));
						users = UserServiceDelegator.getList(searchCriteria);
						if(users!=null && users.size()>0)
						CommonFunctionDelegator.GeneralDelete(users.get(0));
						addActionMessage(users.get(0).getUserId()+" deleted successfully ");
					}catch (Exception e) {
						addActionError("unable to delete  " + users.get(0).getUserId());
					}
				}
			}
		}
		if (logger.isDebugEnabled()) {
			logger.debug("execute() - start");
		}
		SearchCriteria searchCriteria = new SearchCriteria();
		if(operation != null && operation.startsWith(SEARCH)){
			if(group==null)
			ActionContext.getContext().getSession().remove("searchCriteria");
			page=true;
			if(!StringUtils.isBlank(balanceEuroFrom) && !StringUtils.isBlank(balanceEuroTo)){
				if(StringUtils.isNumeric(balanceEuroFrom) && StringUtils.isNumeric(balanceEuroTo)){
					searchCriteria.setBalanceFrom(Double.parseDouble(balanceEuroFrom));
					searchCriteria.setBalanceTo(Double.parseDouble(balanceEuroTo));
				}else{
					addActionError("Please enter valid numeric data");
				}
			}
			if(searchString!=null && searchString.length()>0)
			if(criteria.equals(STATE)){
				searchCriteria.setAttribute(STATE+".categoryName", searchString);
			}else{
				searchCriteria.setAttribute(criteria, searchString);
			}

			if(regionSearch!=null && regionSearch > 0)
				searchCriteria.setAttribute("region".intern(), new LocationCategories(regionSearch));
			if(countrySearch!=null && countrySearch>0)
				searchCriteria.setAttribute(COUNTRY.intern(), new LocationCategories(countrySearch));
				list = UserServiceDelegator.getCaseInsensitiveListOfSearch(searchCriteria);
		}else if(group != null && !group.equals(OTHER)){
			if(ActionContext.getContext().getSession().get("searchCriteria")!=null)
			searchCriteria=(SearchCriteria)ActionContext.getContext().getSession().get("searchCriteria");
			searchCriteria.setAttribute(USER_ID, group);
			list = UserServiceDelegator.getCaseInsensitiveList(searchCriteria);
			searchCriteria.removeAttribute(USER_ID);
		}else if(group != null && group.equals(OTHER)){
			list = UserServiceDelegator.getUserListStartsWithDigit();
			searchCriteria.removeAttribute(USER_ID);
		}else{
			if(ActionContext.getContext().getSession().get("searchCriteria")!=null){
				searchCriteria=(SearchCriteria)ActionContext.getContext().getSession().get("searchCriteria");
			}
			list = UserServiceDelegator.getCaseInsensitiveList(searchCriteria);
		}
		if(list==null || list.size()==0){
			searchCriteria.removeAllAttribute();
			list = UserServiceDelegator.getCaseInsensitiveList(searchCriteria);
		}
		if(list.size()>0){
			userMap = new HashMap<Integer, User>();
			userMapFlag = new HashMap<Integer, User>();
		for (Iterator<User> iterator = list.iterator(); iterator.hasNext();) {
			User user = iterator.next();
			userMap.put(user.getId(), user);
		}
		}
		if(searchCriteria!=null && searchCriteria.getAttributeNames()!=null){
			ActionContext.getContext().getSession().put("searchCriteria", searchCriteria);
		}

		//list
		userAccountsCount = getUserAccountCount();
		}catch (Exception e) {
			e.printStackTrace();
			userAccountsCount = getUserAccountCount();
			addActionError("Unable to update");
		}

		if (logger.isDebugEnabled()) {
			logger.debug("execute() - end");
		}
		if(!paging){
			page=false;
		}


		if(getActionErrors().isEmpty())
		return SUCCESS;
		else return INPUT;
	}

	/** The account search list. */
	private static List<AccountManagerOption> accountSearchList;

	private  List<LocationCategories> country = new ArrayList<LocationCategories>();

	private  List<LocationCategories> region;

	private Integer countrySearch;

	private Integer regionSearch;

	private List<LocationCategories> regionList;

	/** The list. */
	private List<User> list;

	/** The group. */
	private String group;

	/** The selected user deleted. */
	private String[] selectedUserDeleted;



	private Map<Integer, User> userMap;

	private Map<Integer, User> userMapFlag;

	/** The criteria. */
	private String criteria;

	/** The spent euro from. */
	private String spentEuroFrom;

	/** The spent euro to. */
	private String spentEuroTo;

	/** The balance euro to. */
	private String balanceEuroTo;

	/** The balance euro from. */
	private String balanceEuroFrom;

	/** The search string. */
	private String searchString;

	/** The operation. */
	private String operation;

	/** The count. */
	private int count=1;

	/** The user accounts count. */
	UserAccountsCount userAccountsCount;

	/**
	 * Populate account search list with predefine search criteria.
	 *
	 */
	public void populateAccountSearchList(){
		if(accountSearchList==null){
		if (logger.isDebugEnabled()) {
			logger.debug("populateAccountSearchList() - start"); //$NON-NLS-1$
		}
		accountSearchList = new ArrayList<AccountManagerOption>();
		//accountSearchList.add(new AccountManagerOption("Account","Account".intern()));
		accountSearchList.add(new AccountManagerOption(EMAIL,DisplayConstants.EMAIL));
		accountSearchList.add(new AccountManagerOption(WEBSITEADDRESS,DisplayConstants.WEBSITE));
		accountSearchList.add(new AccountManagerOption(PHONE,DisplayConstants.PHONE));
		accountSearchList.add(new AccountManagerOption(FIRSTNAME,DisplayConstants.FIRST_NAME));
		accountSearchList.add(new AccountManagerOption(LASTNAME,DisplayConstants.LAST_NAME));
		accountSearchList.add(new AccountManagerOption(COMPANY,DisplayConstants.COMPANY));
		accountSearchList.add(new AccountManagerOption(STREET,DisplayConstants.STREET));
		accountSearchList.add(new AccountManagerOption(CITY,DisplayConstants.CITY));
		accountSearchList.add(new AccountManagerOption(STATE,DisplayConstants.STATE));
		accountSearchList.add(new AccountManagerOption(ZIP,DisplayConstants.ZIP));

		}


		if (logger.isDebugEnabled()) {
			logger.debug("populateAccountSearchList() - end"); //$NON-NLS-1$
		}

	}

	/**
	 * Gets the user accounts count.
	 *
	 * @return the user accounts count
	 */
	public UserAccountsCount getUserAccountsCount() {
		return userAccountsCount;
	}

	/**
	 * Sets the user accounts count.
	 *
	 * @param userAccountsCount the new user accounts count
	 */
	public void setUserAccountsCount(UserAccountsCount userAccountsCount) {
		this.userAccountsCount = userAccountsCount;
	}

	/**
	 * Gets the list.
	 *
	 * @return the list
	 */
	public List<User> getList() {
		return list;
	}

	/**
	 * Sets the list.
	 *
	 * @param list the new list
	 */
	public void setList(List<User> list) {
		this.list = list;
	}

	/**
	 * Gets the count.
	 *
	 * @return the count
	 */
	public int getCount() {
		return count;
	}

	/**
	 * Sets the count.
	 *
	 * @param count the new count
	 */
	public void setCount(int count) {
		this.count = count;
	}

	/**
	 * Gets the selected user deleted.
	 *
	 * @return the selected user deleted
	 */
	public String[] getSelectedUserDeleted() {
		return selectedUserDeleted;
	}

	/**
	 * Sets the selected user deleted.
	 *
	 * @param selectedUserDeleted the new selected user deleted
	 */
	public void setSelectedUserDeleted(String[] selectedUserDeleted) {
		this.selectedUserDeleted = selectedUserDeleted;
	}



	/**
	 * Gets the group.
	 *
	 * @return the group
	 */
	public String getGroup() {
		return group;
	}

	/**
	 * Sets the group.
	 *
	 * @param group the new group
	 */
	public void setGroup(String group) {
		this.group = group;
	}

	/**
	 * Gets the account search list.
	 *
	 * @return the account search list
	 */
	public List<AccountManagerOption> getAccountSearchList() {
		return accountSearchList;
	}

	/**
	 * Sets the account search list.
	 *
	 * @param accountSearchList the new account search list
	 */
	public void setAccountSearchList(List<AccountManagerOption> accountSearchList) {
		this.accountSearchList = accountSearchList;
	}

	/**
	 * Gets the criteria.
	 *
	 * @return the criteria
	 */
	public String getCriteria() {
		return criteria;
	}

	/**
	 * Sets the criteria.
	 *
	 * @param criteria the new criteria
	 */
	public void setCriteria(String criteria) {
		this.criteria = criteria;
	}

	public Integer getPageSize() {
		return pageSize;
	}

	public void setPageSize(Integer pageSize) {
		this.pageSize = pageSize;
	}

	/**
	 * Gets the spent euro from.
	 *
	 * @return the spent euro from
	 */
	public String getSpentEuroFrom() {
		return spentEuroFrom;
	}

	/**
	 * Sets the spent euro from.
	 *
	 * @param spentEuroFrom the new spent euro from
	 */
	public void setSpentEuroFrom(String spentEuroFrom) {
		this.spentEuroFrom = spentEuroFrom;
	}

	/**
	 * Gets the spent euro to.
	 *
	 * @return the spent euro to
	 */
	public String getSpentEuroTo() {
		return spentEuroTo;
	}

	/**
	 * Sets the spent euro to.
	 *
	 * @param spentEuroTo the new spent euro to
	 */
	public void setSpentEuroTo(String spentEuroTo) {
		this.spentEuroTo = spentEuroTo;
	}

	/**
	 * Gets the balance euro to.
	 *
	 * @return the balance euro to
	 */
	public String getBalanceEuroTo() {
		return balanceEuroTo;
	}

	/**
	 * Sets the balance euro to.
	 *
	 * @param balanceEuroTo the new balance euro to
	 */
	public void setBalanceEuroTo(String balanceEuroTo) {
		this.balanceEuroTo = balanceEuroTo;
	}

	/**
	 * Gets the balance euro from.
	 *
	 * @return the balance euro from
	 */
	public String getBalanceEuroFrom() {
		return balanceEuroFrom;
	}

	/**
	 * Sets the balance euro from.
	 *
	 * @param balanceEuroFrom the new balance euro from
	 */
	public void setBalanceEuroFrom(String balanceEuroFrom) {
		this.balanceEuroFrom = balanceEuroFrom;
	}

	/**
	 * Gets the search string.
	 *
	 * @return the search string
	 */
	public String getSearchString() {
		return searchString;
	}

	/**
	 * Sets the search string.
	 *
	 * @param searchString the new search string
	 */
	public void setSearchString(String searchString) {
		this.searchString = searchString;
	}

	/**
	 * Gets the operation.
	 *
	 * @return the operation
	 */
	public String getOperation() {
		return operation;
	}

	/**
	 * Sets the operation.
	 *
	 * @param operation the new operation
	 */
	public void setOperation(String operation) {
		this.operation = operation;
	}


	/**
	 * @return the userMap
	 */
	public Map<Integer, User> getUserMap() {
		return userMap;
	}

	/**
	 * @param userMap the userMap to set
	 */
	public void setUserMap(Map<Integer, User> userMap) {
		this.userMap = userMap;
	}

	/**
	 * @return the country
	 */
	public  List<LocationCategories> getCountry() {
		return country;
	}

	/**
	 * @param country the country to set
	 */
	public  void setCountry(List<LocationCategories> country) {
		this.country = country;
	}

	/**
	 * @return the countrySearch
	 */
	public Integer getCountrySearch() {
		return countrySearch;
	}

	/**
	 * @param countrySearch the countrySearch to set
	 */
	public void setCountrySearch(Integer countrySearch) {
		this.countrySearch = countrySearch;
	}

	/**
	 * @return the region
	 */
	public  List<LocationCategories> getRegion() {
		return region;
	}

	/**
	 * @param region the region to set
	 */
	public void setRegion(List<LocationCategories> region) {
		this.region = region;
	}

	/**
	 * @return the regionSearch
	 */
	public Integer getRegionSearch() {
		return regionSearch;
	}

	/**
	 * @param regionSearch the regionSearch to set
	 */
	public void setRegionSearch(Integer regionSearch) {
		this.regionSearch = regionSearch;
	}

	public List<LocationCategories> getCountryList() {
		ValueStack stack = ServletActionContext.getValueStack(ServletActionContext.getRequest());
		Object key = stack.findValue(TOP);
		if (key != null && key instanceof LocationCategories) {
			List<LocationCategories> l =new ArrayList<LocationCategories>();
			l.add(new LocationCategories(0,SELECT_A_COUNTRY));
			SearchCriteria  searchCriteria=new SearchCriteria();
			searchCriteria.setAttribute("categoryId", ((LocationCategories)key).getCategoryId());
			List<LocationCategories> list =LocationCategoriesServiceDelegator.getList(searchCriteria);
			if(list!=null && list.size() >0)
			l.addAll(list.get(0).getLocationCategorieses());
			return l;
		}
		return Collections.EMPTY_LIST;
	}

//	@Override
	public void setServletContext(ServletContext arg0) {
		application = arg0;
	}

	/**
	 * @return the regionList
	 */
	public List<LocationCategories> getRegionList() {
		return regionList;
	}

	/**
	 * @param regionList the regionList to set
	 */
	public void setRegionList(List<LocationCategories> regionList) {
		this.regionList = regionList;
	}

	/**
	 * @return the userMapFlag
	 */
	public Map<Integer, User> getUserMapFlag() {
		return userMapFlag;
	}

	/**
	 * @param userMapFlag the userMapFlag to set
	 */
	public void setUserMapFlag(Map<Integer, User> userMapFlag) {
		this.userMapFlag = userMapFlag;
	}

	private UserAccountsCount getUserAccountCount() {
		UserAccountsCount userAccountsCount = new UserAccountsCount();

		if(list != null) {
		for (User user : list) {
			if(user.getUserId().toLowerCase().startsWith("a"))
				userAccountsCount.setAa(userAccountsCount.getAa() + 1);
			else if(user.getUserId().toLowerCase().startsWith("b"))
				userAccountsCount.setBb(userAccountsCount.getBb() + 1);
			else if(user.getUserId().toLowerCase().startsWith("c"))
				userAccountsCount.setCc(userAccountsCount.getCc() + 1);
			else if(user.getUserId().toLowerCase().startsWith("d"))
				userAccountsCount.setDd(userAccountsCount.getDd() + 1);
			else if(user.getUserId().toLowerCase().startsWith("e"))
				userAccountsCount.setEe(userAccountsCount.getEe() + 1);
			else if(user.getUserId().toLowerCase().startsWith("f"))
				userAccountsCount.setFf(userAccountsCount.getFf() + 1);
			else if(user.getUserId().toLowerCase().startsWith("g"))
				userAccountsCount.setGg(userAccountsCount.getGg() + 1);
			else if(user.getUserId().toLowerCase().startsWith("h"))
				userAccountsCount.setHh(userAccountsCount.getHh() + 1);
			else if(user.getUserId().toLowerCase().startsWith("i"))
				userAccountsCount.setIi(userAccountsCount.getIi() + 1);
			else if(user.getUserId().toLowerCase().startsWith("j"))
				userAccountsCount.setJj(userAccountsCount.getJj() + 1);
			else if(user.getUserId().toLowerCase().startsWith("k"))
				userAccountsCount.setKk(userAccountsCount.getKk() + 1);
			else if(user.getUserId().toLowerCase().startsWith("l"))
				userAccountsCount.setLl(userAccountsCount.getLl() + 1);
			else if(user.getUserId().toLowerCase().startsWith("m"))
				userAccountsCount.setMm(userAccountsCount.getMm() + 1);
			else if(user.getUserId().toLowerCase().startsWith("n"))
				userAccountsCount.setNn(userAccountsCount.getNn() + 1);
			else if(user.getUserId().toLowerCase().startsWith("o"))
				userAccountsCount.setOo(userAccountsCount.getOo() + 1);
			else if(user.getUserId().toLowerCase().startsWith("p"))
				userAccountsCount.setPp(userAccountsCount.getPp() + 1);
			else if(user.getUserId().toLowerCase().startsWith("q"))
				userAccountsCount.setQq(userAccountsCount.getQq() + 1);
			else if(user.getUserId().toLowerCase().startsWith("r"))
				userAccountsCount.setRr(userAccountsCount.getRr() + 1);
			else if(user.getUserId().toLowerCase().startsWith("s"))
				userAccountsCount.setSs(userAccountsCount.getSs() + 1);
			else if(user.getUserId().toLowerCase().startsWith("t"))
				userAccountsCount.setTt(userAccountsCount.getTt() + 1);
			else if(user.getUserId().toLowerCase().startsWith("u"))
				userAccountsCount.setUu(userAccountsCount.getUu() + 1);
			else if(user.getUserId().toLowerCase().startsWith("v"))
				userAccountsCount.setVv(userAccountsCount.getVv() + 1);
			else if(user.getUserId().toLowerCase().startsWith("w"))
				userAccountsCount.setWw(userAccountsCount.getWw() + 1);
			else if(user.getUserId().toLowerCase().startsWith("x"))
				userAccountsCount.setXx(userAccountsCount.getXx() + 1);
			else if(user.getUserId().toLowerCase().startsWith("y"))
				userAccountsCount.setYy(userAccountsCount.getYy() + 1);
			else if(user.getUserId().toLowerCase().startsWith("z"))
				userAccountsCount.setZz(userAccountsCount.getZz() + 1);
			else
				userAccountsCount.setOther(userAccountsCount.getOther() + 1);
		}
		}
		return userAccountsCount;
	}
}